/**
 *******************************************************************************
 * @file  hc32f160_pwc.h
 * @brief This file contains all the functions prototypes of the PWC driver
 *        library.
 @verbatim
   Change Logs:
   Date             Author          Notes
   2020-11-27       CDT             First version
 @endverbatim
 *******************************************************************************
 * Copyright (C) 2020, Huada Semiconductor Co., Ltd. All rights reserved.
 *
 * This software component is licensed by HDSC under BSD 3-Clause license
 * (the "License"); You may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *                    opensource.org/licenses/BSD-3-Clause
 *
 *******************************************************************************
 */
#ifndef __HC32F160_PWC_H__
#define __HC32F160_PWC_H__

/* C binding of definitions if building with C++ compiler */
#ifdef __cplusplus
extern "C"
{
#endif

/*******************************************************************************
 * Include files
 ******************************************************************************/
#include "hc32_common.h"
#include "ddl_config.h"

/**
 * @addtogroup HC32F160_DDL_Driver
 * @{
 */

/**
 * @addtogroup DDL_PWC
 * @{
 */

#if (DDL_PWC_ENABLE == DDL_ON)

/*******************************************************************************
 * Global type definitions ('typedef')
 ******************************************************************************/
/**
 * @defgroup PWC_Global_Types PWC Global Types
 * @{
 */

/**
 * @brief PWC stop mode config
 */
typedef struct
{
    uint8_t u8HighPrecisionPOR; /*!< Specifies the high POR(power on reset) on or off while stop mode.
                                    This parameter can be a value of @ref PWC_HPOR_Config.          */
    uint8_t u8SysClockMode;     /*!< Specifies the system clock while awake from stop mode.
                                    This parameter can be a value of @ref PWC_SysClock_config.      */
    uint8_t u8WaitFlash;        /*!< Specifies whether to wait flash after stop mode awake.
                                    This parameter can be a value of @ref PWC_WaitFlash_Config.     */
} stc_pwc_stop_mode_t;

/**
 * @brief PWC LVD config
 */
typedef struct
{
    uint16_t u16ExtInput;           /*!< Specifies the validity of the PWC LVD external input.
                                        This parameter can be a value of @ref PWC_LVD_External_Input.       */
    uint16_t u16ExceptionType;      /*!< Specifies LVD trigger interrupt or reset when voltage meet the condition
                                        This parameter can be a value of @ref PWC_LVD_Exception_Type.       */
    uint16_t u16IntMode;            /*!< Specifies LVD interrupt mode, maskable or non_maskable
                                        This parameter can be a value of @ref PWC_LVD_Interrupt_Mode.       */
    uint16_t u16Filter;             /*!< Specifies the digital filter on or off.
                                        This parameter can be a value of @ref PWC_LVD_Digital_Filter.       */
    uint16_t u16FilterClock;        /*!< Specifies the digital filter sample clock.
                                        This parameter can be a value of @ref PWC_LVD_Digital_Filter_Clock. */
    uint16_t u16ThresholdVoltage;   /*!< Specifies the LVD detect threshole voltage.
                                        This parameter can be a value of @ref PWC_LVD_Threshold_Level.      */
} stc_pwc_lvd_init_t;

/*******************************************************************************
 * Global pre-processor symbols/macros ('#define')
 ******************************************************************************/
/**
 * @defgroup PWC_Global_Macros PWC Global Macros
 * @{
 */

/**
 * @defgroup PWC_HPOR_Config PWC High Precision POR(power on reset) Config
 * @{
 */
#define PWC_HIGH_PRECISION_POR_ON   (0x00U)                 /*!< High precision POR is valid while in stop mode   */
#define PWC_HIGH_PRECISION_POR_OFF  (PWC_STPMCR_HAPORDIS)   /*!< High precision POR is invalid while in stop mode */
/**
 * @}
 */

/**
 * @defgroup PWC_SysClock_config PWC Clock Config
 * @{
 */
#define PWC_SYSCLK_FIX              (0x00U)                 /*!< System clock is fixed after stop mode awake            */
#define PWC_SYSCLK_HRCDIVX          (PWC_STPMCR_CKSHRC)     /*!< System clock is n divided of HRC after stop mode awake */
/**
 * @}
 */

/**
 * @defgroup PWC_WaitFlash_Config PWC wait flash stable function after stop mode awake
 * @{
 */
#define PWC_WAIT_FLASH_ON           (0x00U)                 /*!< Wait flash stable after stop mode awake */
#define PWC_WAIT_FLASH_OFF          (PWC_STPMCR_FLNWT)      /*!< Do not wait flash stable after stop mode awake */
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_External_Input PWC LVD External Input Config
 * @{
 */
#define PWC_LVD_EXT_INPUT_ON        (PWC_LVDCSR_EXVCCINEN)
#define PWC_LVD_EXT_INPUT_OFF       (0x00U)
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Exception PWC LVD exception configure on or off.
 * @{
 */
#define PWC_LVD_EXP_ON              (0x0000U)
#define PWC_LVD_EXP_OFF             (PWC_LVDICGCR_IRDIS)
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Exception_Type LVD exception type
 * @{
 */
#define PWC_LVD_EXP_TYPE_INT        (0x00U)                 /*!< LVD select interrupt */
#define PWC_LVD_EXP_TYPE_RST        (EFM_PWC_LVDICGCR_IRS)      /*!< LVD select reset */
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Interrupt_Mode PWC LVD interrupt mode maskable or non_maskable
 * @{
 */
#define PWC_LVD_INT_MASK            (0x0000U)
#define PWC_LVD_INT_NONMASK         (EFM_PWC_LVDICGCR_NMIS)
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Digital_Filter LVD digital filter on or off
 * @{
 */
#define PWC_LVD_DIG_FILTER_ON       (0x0000U)
#define PWC_LVD_DIG_FILTER_OFF      (EFM_PWC_LVDICGCR_DFDIS)
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Digital_Filter_Clock LVD digital filter sample clock config.
 * @note     modified this value must when PWC_LVD_DF_OFF
 * @{
 */
#define PWC_LVD_DIG_FILTER_CLK_2LRC  (0x0000U)     /*!< 2 LRC cycle    */
#define PWC_LVD_DIG_FILTER_CLK_4LRC  (0x0001U)     /*!< 4 LRC cycle    */
#define PWC_LVD_DIG_FILTER_CLK_8LRC  (0x0002U)     /*!< 8 LRC cycle    */
#define PWC_LVD_DIG_FILTER_CLK_16LRC (0x0003U)     /*!< 16 LRC cycle   */
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_Threshold_Level PWC LVD Threshold Level
 * @{
 */
#define PWC_LVD_THRESHOLD_LEVEL0    (0x0000U)    /*!< Specifies the voltage range 3.92V~4.07V.    */
#define PWC_LVD_THRESHOLD_LEVEL1    (0x0100U)    /*!< Specifies the voltage range 3.67V~3.77V.    */
#define PWC_LVD_THRESHOLD_LEVEL2    (0x0200U)    /*!< Specifies the voltage range 3.06V~3.15V.    */
#define PWC_LVD_THRESHOLD_LEVEL3    (0x0300U)    /*!< Specifies the voltage range 2.96V~3.04V.    */
#define PWC_LVD_THRESHOLD_LEVEL4    (0x0400U)    /*!< Specifies the voltage range 2.86V~2.94V.    */
#define PWC_LVD_THRESHOLD_LEVEL5    (0x0500U)    /*!< Specifies the voltage range 2.75V~2.83V.    */
#define PWC_LVD_THRESHOLD_LEVEL6    (0x0600U)    /*!< Specifies the voltage range 2.65V~2.73V.    */
#define PWC_LVD_THRESHOLD_LEVEL7    (0x0700U)    /*!< Specifies the voltage range 2.55V~2.63V.    */
#define PWC_LVD_THRESHOLD_LEVEL8    (0x0800U)    /*!< Specifies the voltage range 2.45V~2.52V.    */
#define PWC_LVD_THRESHOLD_LEVEL9    (0x0900U)    /*!< Specifies the voltage range 2.04V~2.11V.    */
#define PWC_LVD_THRESHOLD_LEVEL10   (0x0A00U)    /*!< Specifies the voltage range 1.94V~2.00V.    */
#define PWC_LVD_THRESHOLD_LEVEL11   (0x0B00U)    /*!< Specifies the voltage range 1.84V~1.90V.    */
#define PWC_LVD_THRESHOLD_EXT_INPUT (0x0E00U)    /*!< LVD use external input reference voltage    */
/**
 * @}
 */

/**
 * @defgroup PWC_Monitor_Power PWC Power Monitor voltage definition
 * @{
 */
#define PWC_MON_PWR_IREF            (0x00U)                 /*!< Internal reference voltage */
#define PWC_MON_PWR_TSENSOR         (PWC_PWRMON_PWMONSEL)   /*!< temperature sensor voltage */
/**
 * @}
 */

/**
 * @defgroup PWC_Dynamic_Voltage PWC Dynamic Voltage selection
 * @{
 */
#define PWC_DYNAMIC_VOLTAGE_1P6V    (0x00U)                 /*!< VDD = 1.6V */
#define PWC_DYNAMIC_VOLTAGE_1P5V    (PWC_PWRC_DVS)          /*!< VDD = 1.5V */
/**
 * @}
 */

/**
 * @defgroup PWC_LVD_FLAG PWC LVD Flag
 * @{
 */
#define PWC_LVD_FLAG_DET            (PWC_LVDCSR_DETF)       /*!< VDD = VLVD or LVDINP = VInref  */
#define PWC_LVD_FLAG_LVI            (PWC_LVDCSR_LVIF)       /*!< VCC < VLVD                     */
/**
 * @}
 */

/**
 * @defgroup PWC_RAM_protect_area PWC ram protect area selection
 * @{
 */
#define PWC_RAM_PROTECT_NONE        (0x00U)
#define PWC_RAM_PROTECT_128BYTE     (0x01U)
#define PWC_RAM_PROTECT_256BYTE     (0x02U)
#define PWC_RAM_PROTECT_512BYTE     (0x03U)
/**
 * @}
 */

/**
 * @}
 */


/**
 * @defgroup PWC_REG_Write_Unlock_Code PWC register unlock code.
 * @brief Lock/unlock Code for each module
 *        PWC_UNLOCK_CODE_0:
 *          Below registers are locked in CLK module.
 *              PERICKSEL, XTALSTDSR, SCKDIVR, CKSWR, XTALCR, XTALCFGR, XTALSTBCR,
 *              HRCCR, OSCSTBSR, MCO1CFGR, XTALSTDCR, FCG, XTAL32CR, XTAL32CFGR,
 *              XTAL32NFR, LRCCR
 *        PWC_UNLOCK_CODE_1:
 *          Below registers are locked in PWC module.
 *              STPMCR, PWRC, PWRMON, RAMCR, DBGC
 *          Below register is locked in RMU module.
 *              RSTF0
 *        PWC_UNLOCK_CODE_2:
 *          Below registers are locked in PWC module.
 *              LVDCSR, LVDICGCR
 * @{
 */
#define PWC_UNLOCK_CODE_0           (0xA501U)
#define PWC_UNLOCK_CODE_1           (0xA502U)
#define PWC_UNLOCK_CODE_2           (0xA508U)
/**
 * @}
 */

/*******************************************************************************
 * Global variable definitions ('extern')
 ******************************************************************************/

/*******************************************************************************
  Global function prototypes (definition in C source)
 ******************************************************************************/
/**
 * @addtogroup PWC_Global_Functions
 * @{
 */

/**
 * @brief  Lock PWC, CLK, RMU register.
 * @param  [in] u16Module Lock code for each module.
 *   @arg  PWC_UNLOCK_CODE_0:
 *          Below registers are locked in CLK module.
 *              PERICKSEL, XTALSTDSR, SCKDIVR, CKSWR, XTALCR, XTALCFGR, XTALSTBCR,
 *              HRCCR, OSCSTBSR, MCO1CFGR, XTALSTDCR, FCG, XTAL32CR, XTAL32CFGR,
 *              XTAL32NFR, LRCCR
 *   @arg  PWC_UNLOCK_CODE_1:
 *          Below registers are locked in PWC module.
 *              STPMCR, PWRC, PWRMON, RAMCR, DBGC
 *          Below register is locked in RMU module.
 *              RSTF0
 *   @arg  PWC_UNLOCK_CODE_2:
 *          Below registers are locked in PWC module.
 *              LVDCSR, LVDICGCR
 * @retval None
 */
__STATIC_INLINE void PWC_Lock(uint16_t u16Module)
{
    WRITE_REG16(CM_PWC->FPRC, (0xA500U | (uint16_t)((uint16_t)(~u16Module) & (CM_PWC->FPRC))));
}

/**
 * @brief  Unlock PWC, CLK, RMU register.
 * @param  [in] u16Module Unlock code for each module.
 *   @arg  PWC_UNLOCK_CODE_0:
 *          Below registers are unlocked in CLK module.
 *              PERICKSEL, XTALSTDSR, SCKDIVR, CKSWR, XTALCR, XTALCFGR, XTALSTBCR,
 *              HRCCR, OSCSTBSR, MCO1CFGR, XTALSTDCR, FCG, XTAL32CR, XTAL32CFGR,
 *              XTAL32NFR, LRCCR
 *   @arg  PWC_UNLOCK_CODE_1:
 *          Below registers are unlocked in PWC module.
 *              STPMCR, PWRC, PWRMON, RAMCR, DBGC
 *          Below register is unlocked in RMU module.
 *              RSTF0
 *   @arg  PWC_UNLOCK_CODE_2:
 *          Below registers are unlocked in PWC module.
 *              LVDCSR, LVDICGCR
 * @retval None
 */
__STATIC_INLINE void PWC_Unlock(uint16_t u16Module)
{
    SET_REG16_BIT(CM_PWC->FPRC, u16Module);
}

void PWC_Lock(uint16_t u16Module);
void PWC_Unlock(uint16_t u16Module);

void PWC_EnterStopMode(void);
void PWC_EnterSleepMode(void);

void PWC_HighSpeedToLowSpeed(void);
void PWC_LowSpeedToHighSpeed(void);

en_result_t PWC_StopStructInit(stc_pwc_stop_mode_t* pstcStopConfig);
en_result_t PWC_StopModeConfig(const stc_pwc_stop_mode_t* pstcStopConfig);

void PWC_SetDynamicVoltage(uint8_t u8DynamicVoltage);
void PWC_HrcLDOCmd(en_functional_state_t enNewState);
en_flag_status_t PWC_GetHrcLDOStatus(void);

void PWC_MonitorPowerCmd(en_functional_state_t enNewState);
void PWC_MonitorPwrSelect(uint8_t u8PowerSelect);

en_result_t PWC_LVD_StructInit(stc_pwc_lvd_init_t* pstcLvdInit);
en_result_t PWC_LVD_Init(const stc_pwc_lvd_init_t* pstcLvdInit);

void PWC_LVD_Cmd(en_functional_state_t enNewState);
void PWC_LVD_ExtInputCmd(en_functional_state_t enNewState);
void PWC_LVD_ExceptionCmd(en_functional_state_t enNewState);
void PWC_LVD_DigitalFilterCmd(en_functional_state_t enNewState);
void PWC_LVD_CompareOutputCmd(en_functional_state_t enNewState);

void PWC_LVD_SetIntMode(uint16_t u16IntMode);
void PWC_LVD_SetFilterClock( uint16_t u16FilterClock);
void PWC_LVD_SetExceptionType(uint16_t u16ExceptionType);
void PWC_LVD_SetVoltageThreshold(uint16_t u16VoltageThreshold);

en_flag_status_t PWC_GetLvdFlag(uint8_t u8Flag);
void PWC_ClearLvdDetectFlag(void);

void PWC_RamProtectAreaConfig(uint8_t u8ProtectArea);
void PWC_RamParityResetCmd(en_functional_state_t enNewState);
en_flag_status_t PWC_GetRamParityStatus(void);
void PWC_ClearRamParityStatus(void);

void PWC_DebugCmd(en_functional_state_t enNewState);
/**
 * @}
 */

#endif /* DDL_PWC_ENABLE */

/**
 * @}
 */

/**
 * @}
 */

/**
 * @}
 */

#ifdef __cplusplus
}
#endif

#endif /* __HC32F160_PWC_H__ */

/*******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
